#_*_ coding:UTF-8 _*_

import os
from ConnectTrack import ConnectTrack
import  time
import copy
import math

class StopAndlook:
    '''
    该类主要用来判断顾客是否看车
    '''

    def __init__(self):
        pass

    def isStop(self,startAndEnd,threshold,allIdMap,trackspath,trueIDMap):
        '''
        把顾客在不同摄像头下看车的轨迹合并起来，通过帧数的多少来判断顾客是否看车
        :param startAndEnd:dict{摄像头id：{车辆id：{顾客id：坐标（list）}}}
        :param threshold:判断顾客是否看车的阈值（int）
        :param allIdMap:存储各个摄像头下的ID之间的映射关系（dict）
        :param trackspath:(dict)每所有摄像头对应的顾客轨迹的DataFrame{摄像头ID：DataFrame}
        :param trueIDMap:(dict)不同摄像头下真实ID和临时ID之间的映射关系（通过拼接得到的）
        :return:看车顾客的合集dict {车辆id：{顾客id：坐标（list）}}
        '''

        #先映射
        connectIdMap=copy.deepcopy(trueIDMap)
        startAndEnd1=copy.deepcopy(startAndEnd)
        ct=ConnectTrack(trackspath,allIdMap)#轨迹拼接
        newSAE={}

        for camerakey in startAndEnd1:

            # print "单个摄像头下的顾客看车-start" + str(time.time())
            idMap=allIdMap[camerakey]#单个摄像头下轨迹映射关系（临时ID有对应的真实ID，无需拼接得到，从原始文件中可以得到）
            if trueIDMap.has_key(camerakey):
                aloneIdMAp=trueIDMap[camerakey]#单个摄像头拼接的轨迹映射关系
            else:
                aloneIdMAp={}
            ct.setIdMap(idMap)
            data=trackspath[camerakey]
            data=data[data.is_customer==1]

            ct.setTrackFile(data)
            # realId=allRealId[camerakey]
            tempCar={}
            # print camerakey
            for carkey in startAndEnd1[camerakey]:
                tempConsumer=startAndEnd1[camerakey][carkey]
                tempCon={}

                for consumerkey in tempConsumer:
                    # x=tempConsumer[consumerkey]
                    real=idMap[consumerkey]
                    if real!="" :#有对应的真实ID
                        # print  tempCon
                        if  tempCon.has_key(real):
                            tempCon[real].extend(tempConsumer[consumerkey])
                        else:
                            tempCon[real] = tempConsumer[consumerkey]
                            # y= tempCon[real]
                    else:#没有对应的真实ID，则进行拼接
                        if aloneIdMAp.has_key(consumerkey) and  not tempCon.has_key(aloneIdMAp[consumerkey]):
                            tempCon[aloneIdMAp[consumerkey]] = tempConsumer[consumerkey]
                        elif aloneIdMAp.has_key(consumerkey) and   tempCon.has_key(aloneIdMAp[consumerkey]):
                            tempCon[aloneIdMAp[consumerkey]].extend(tempConsumer[consumerkey])
                        else:
                            tempList=ct.connect(consumerkey)
                            if idMap[tempList[-1]]!="" and  not tempCon.has_key(idMap[tempList[-1]]):
                                tempCon[idMap[tempList[-1]]] = tempConsumer[consumerkey]
                                connectIdMap[consumerkey]=idMap[tempList[-1]]
                            elif idMap[tempList[-1]]!="" and  tempCon.has_key(idMap[tempList[-1]]):
                                tempCon[idMap[tempList[-1]]].extend(tempConsumer[consumerkey])
                                connectIdMap[consumerkey] = idMap[tempList[-1]]
                tempCar[carkey]=tempCon
            newSAE[camerakey]=tempCar

            # print "单个摄像头下的顾客看车-end" + str(time.time())

        cars=[]
        consumers=[]
        # for camerakey in startAndEnd:
        for camerakey in newSAE:
            tempdict=newSAE[camerakey]
            for carkey in tempdict:
                if carkey not in cars:
                    cars.append(carkey)#所有的车辆ID
                tempdict1=tempdict[carkey]

                if tempdict1:
                    for consumerkey in tempdict1:
                        if consumerkey not in consumers:
                            consumers.append(consumerkey)#所有的顾客ID


        #合并轨迹，合并轨迹之前必须进行id之间的映射
        allTracks={}   #{carid:{consumerid:coord(list)}}
        for i in cars:
            tempcardict={}
            for j in  consumers:
                tempconsumerlist=[]
                for camerakey in newSAE:
                    #print  i,j
                    temp1=newSAE[camerakey]
                    if i in temp1.keys():
                        temp2=temp1[i]
                        if j in temp2.keys():
                            temp3=temp2[j]
                            tempconsumerlist.extend(temp3)


                tempconsumerlist.sort(key=lambda x:float(x.strip(" ").split(",")[0]))
                #判断上车的策略有一点问题
                if len(tempconsumerlist)>=2:
                    #顾客看车的条件是在车辆周围待了足够的时间
                    if  float(tempconsumerlist[-1].split(",")[0])- float(tempconsumerlist[0].split(",")[0]) \
                        >= float(threshold) and len(tempconsumerlist)>=threshold/250:

                        tempcardict[j]=tempconsumerlist

            allTracks[i]=tempcardict

        return  allTracks,connectIdMap#此处的看车顾客已经是映射完成后的看车顾客

    def isStopTempId(self,startAndEnd,threshold,trackspath):
        '''
        通过临时id来判断顾客的看车情况
        :param startAndEnd:dict{摄像头id：{车辆id：{顾客id：坐标（list）}}}
        :param threshold:判断顾客是否看车的阈值（int）
        :param trackspath:(dict)每所有摄像头对应的顾客轨迹的DataFrame{摄像头ID：DataFrame}
        :return:看车顾客的合集dict {车辆id：{顾客id：坐标（list）}}
        '''

        #先映射
        startAndEnd1=copy.deepcopy(startAndEnd)

        cars=[]
        carsNum={}#统计车辆在摄像头中出现的次数
        consumers=[]
        # for camerakey in startAndEnd:
        for camerakey in startAndEnd1:
            tempdict=startAndEnd1[camerakey]
            for carkey in tempdict:
                if carsNum.has_key(carkey):
                    carsNum[carkey]=carsNum[carkey]+1
                else:
                    carsNum[carkey]=1
                if carkey not in cars:
                    cars.append(carkey)#所有的车辆ID
                tempdict1=tempdict[carkey]

                if tempdict1:
                    for consumerkey in tempdict1:
                        if consumerkey not in consumers:
                            consumers.append(consumerkey)#所有的顾客ID


        #单上相投下临时ID看车的情况
        allLookCar={}
        for camerakey in startAndEnd1:
            tempdict = startAndEnd1[camerakey]
            lookcarInCar={}
            for carkey in tempdict:
                tmpConsumer=tempdict[carkey]
                lookcar={}
                for consumerkey in tmpConsumer:
                    consumerList=tmpConsumer[consumerkey]
                    if float(consumerList[-1].split(",")[0]) - float(consumerList[0].split(",")[0]) \
                            >= float(threshold) and len(consumerList) >= threshold / 250:
                        lookcar[consumerkey] = consumerList
                lookcarInCar[carkey]=lookcar
            allLookCar[camerakey]=lookcarInCar

        #统计看车人数和看车时长
        lookcarNum={}#看车人数
        lookcarTime={}#看车时长

        for i in cars:
                for camerakey in allLookCar:
                    temp1 = allLookCar[camerakey]
                    if  i in  temp1.keys():
                        temp2 = temp1[i]
                        #统计看车人数
                        if lookcarNum.has_key(i):
                            lookcarNum[i]=lookcarNum[i]+len(temp2.keys())
                        else:
                            lookcarNum[i] = len(temp2.keys())
                        #遍历每个顾客
                        for j in consumers:
                            if j in temp2.keys():
                                temp3 = temp2[j]
                                #统计车辆被看的帧数
                                if lookcarTime.has_key(i):
                                    lookcarTime[i]=lookcarTime[i]+len(temp3)
                                else:lookcarTime[i]=len(temp3)

        return  allLookCar,lookcarTime,lookcarNum,carsNum,allLookCar#看车的顾客轨迹，车辆被看的时间，车辆被看的次数，车辆在不同摄像头下出现的次数,各个摄像头下看车的临时ID

    def getLookCarNumRatio(self,lookCarTempId,carId,allIdMap):
        '''
        获取看车次数的比率
        :param lookCarTempId: （dict）看车顾客的临时ID
        :param carId: （list）车辆ID
        :param allIdMap: （dict）真实Id和临时ID的映射
        :return:
        '''
        lookNum={}
        # 获取看车的比率
        for camerkary in lookCarTempId:
            allcar=lookCarTempId[camerkary]
            temp={}
            for carkey in allcar:
                lookNumTmp=len(allcar[carkey].keys())
                allConsumer=len(allIdMap[camerkary].keys())
                ratio=float(lookNumTmp)/(float(allConsumer)*0.75)
                temp[carkey]=ratio
            lookNum[camerkary]=temp

        #合并顾客看车的比率
        allLookCarNum={}
        for car in carId:
            for camerakey in lookNum:
                t=lookNum[camerakey]
                if t.has_key(car):
                    if allLookCarNum.has_key(car):
                        allLookCarNum[car]=allLookCarNum[car]+t[car]*0.5#有一半的看车顾客和之前其他摄像头下看车看车的顾客是重复的
                    else:
                        allLookCarNum[car]=t[car]
        return allLookCarNum

    def getBoardNumRatio(self,boardTempId,carId,allIdMap):
        '''
        获取上车次数的比率
        :param boardTempId: （dict）上车顾客的临时ID
        :param carId: （list）车辆ID
        :param allIdMap: （dict）真实Id和临时ID的映射
        :return:
        '''
        lookNum={}
        # 获取看车的比率
        for camerkary in boardTempId:
            allcar=boardTempId[camerkary]
            temp={}
            for carkey in allcar:
                lookNumTmp=len(allcar[carkey])
                allConsumer=len(allIdMap[camerkary].keys())
                ratio=float(lookNumTmp)/(float(allConsumer)*0.75)#
                temp[carkey]=ratio
            lookNum[camerkary]=temp

        #合并顾客看车的比率
        allLookCarNum={}
        for car in carId:
            for camerakey in lookNum:
                t=lookNum[camerakey]
                if t.has_key(car):
                    if allLookCarNum.has_key(car):
                        allLookCarNum[car]=allLookCarNum[car]+t[car]*0.75#有四分之一的上车车顾客和之前其他摄像头下上车看车的顾客是重复的
                    else:
                        allLookCarNum[car]=t[car]
        return allLookCarNum


    # def getCarCationNum(self,lookCarNumRatio,boardNumRation,consumerNum,carsNum,famillyLookCar,famillyBoard):#把人群按比例分配到上车和看车顾客中
    def getCarCationNum(self, lookCarNumRatio, boardNumRation, consumerNum,cameras,famillyRatio):
        '''
        得到行人的车前行为数据（看车和上车）
        :param lookCarNumRatio:（dict）看车顾客占总人数的比例（临时id）
        :param boardNumRation:（dict）上车车顾客占总人数的比例（临时id）
        :param consumerNum:（int）人流总数（没有去处人群）
        :param cameras:（dict）车辆在摄像头下出现的位置
        :param famillyRatio:（float)人群占总人流数的比例
        :param famillyBoard:（dict）顾客上车时人群在各个车辆中的比例
        :return:（dict）看每辆车的总人数和上每辆车的总人数
        '''
        '''
        在按比例将临时id的看车顾客映射成真实ID时，人流的总数要乘以摄像头的个数，表示一个顾客可能在多个摄像头下出现，
        摄像头的数量可以反映出4S店的大小，店越大人就应该越多。如果不乘以摄像头的数量，则映射严重失准
        '''
        allConsumer=float(consumerNum)*len(cameras.keys())*0.5#总客流*摄像头的数量
        lookCarNum={}#看车人数
        for carkey in lookCarNumRatio:#按比例算出看车人数
            lookCarNum[carkey]=math.ceil(float(allConsumer)*lookCarNumRatio[carkey])
        lookCarNum1={}
        for carkey in lookCarNum:#去除群体顾客，通过群体顾客占总人数的比例
            lookCarNum1[carkey]=math.ceil(lookCarNum[carkey]*famillyRatio)
            # lookCarNum1[carkey] = lookCarNum[carkey] - famillyLookCar[carkey]
        # lookCarNum2={}
        # for carkey in lookCarNum1:#去除多摄像头的影响
        #     lookCarNum2[carkey]=math.ceil(lookCarNum1[carkey]/float(carsNum[carkey]))

        boardNum={}#上车人数
        for carkey in boardNumRation:
            boardNum[carkey]=math.ceil(float(allConsumer)*boardNumRation[carkey])
        boardNum1={}
        for carkey in boardNum:
            boardNum1[carkey]=boardNum[carkey]
            # boardNum1[carkey] = boardNum[carkey] - famillyBoard[carkey]
        # boardNum2={}
        # for carkey in boardNum1:
        #     boardNum2[carkey]=math.ceil(boardNum1[carkey]/float(carsNum[carkey]))

        return lookCarNum1,boardNum1


    def  stopConsumer(self,cameras,allData,dc,threshold,allIdMap):
        '''
        在所有的顾客中提取出在某个摄像头的某辆车下有停留的顾客（有停留不一定是看车）
        :param cameras:(dict)所有摄像头下每个车辆的坐标：{摄像头id：{车辆Id：坐标（x,y,width,height）string}}
        :param allData:(dict)每所有摄像头对应的顾客轨迹的DataFrame{摄像头ID：DataFrame}
        :param dc:DataCleaning类实例
        :param threshold:(float)用户与车辆矩形面积重合的阈值
        :return:（dict）所有在车辆周围有停留的顾客的信息{摄像头id（str）=》{车id（str）=》{顾客id（str）=》坐标（list）}}}
        '''
        result={}#{摄像头id（str）=》{车id（str）=》{顾客id（str）=》坐标（list）}}}
        for camerakey in cameras:
            oneCamera={}
            dc.setFileName(allData[camerakey])
            carCoord=cameras[camerakey]#当前摄像头下的车辆位置

            if  not carCoord :#摄像头下没有车辆，直接跳过
                continue
            data1 = allData[camerakey]
            idMap = allIdMap[camerakey]
            data = data1[data1.is_customer == 1]
            for  carkey in carCoord:
                temp={}
                #其实，可以在这一步就做映射，可以减轻后面的计算量
                for k in idMap.keys():#遍历所有的顾客
                    i=str(k)
                    # print i
                    consumersCoord = []
                    allLine=data[data.tmp_id==float(i)].values
                    for eachLine in allLine:#对顾客每个轨迹和车辆位置进行比较
                        line=eachLine[0:len(eachLine)-1]
                        line=map(str,line)
                        consumerCoord=[]
                        if len(line)==6:
                            consumerCoord.append(line[2])#x
                            consumerCoord.append(line[3])#y
                            consumerCoord.append(line[4])#width
                            consumerCoord.append(line[5])#height
                        carCoord1=carCoord[carkey].split(",")#车辆位置坐标
                        overlop=dc.overlopArea(carCoord1,consumerCoord)#与车辆之间的距离
                        if overlop >=threshold:
                            eachLine1=",".join(line)+","+str(overlop)
                            consumersCoord.append(eachLine1)

                        del consumerCoord
                    if consumersCoord:
                        temp[i]=consumersCoord
                if temp:
                    oneCamera[carkey]=temp
            if  oneCamera:
                result[camerakey]=oneCamera

        return  result


    def mergeComsumer(self,startAndEnd):
        '''
        合并多个摄像头下有停留的顾客
        :param stopAndEnd:（dict）所有在车辆周围有停留的顾客的信息{摄像头id（str）=》{车id（str）=》{顾客id（str）=》坐标（list）}}}
        :return:（dict）在车周围有停留的顾客信息{车id（str）=》{顾客id（str）=》坐标（list）}}
        '''
        startAndEnd1=copy.deepcopy(startAndEnd)
        cars=[]
        consumers=[]
        for camerakey in startAndEnd1:
            tempdict=startAndEnd1[camerakey]
            for carkey in tempdict:
                if carkey not in cars:
                    cars.append(carkey)#所有车辆ID
                tempdict1=tempdict[carkey]

                if tempdict1:
                    for consumerkey in tempdict1:
                        if consumerkey not in consumers:
                            consumers.append(consumerkey)#所有顾客ID

        mergeCon={}
        for car in cars:
            tmp={}
            for consumer in consumers:
                tracks=[]
                for camera in startAndEnd1:
                    carnum=startAndEnd1[camera][car]
                    if   carnum.has_key(consumer):
                        consumerTracks=carnum[consumer]
                        for track in consumerTracks:
                            tracks.append(track)

                if len(tracks)>0:
                    tmp[consumer]=tracks
            if len(tmp)>0:
                mergeCon[car]=tmp

        return mergeCon

    def getRealId(self,allRealIdMap):
        '''
        合并多有摄像头下的真实ID
        :param allRealIdMap: （dict）不同摄像头下食物真实ID
        :return: （list）4S店中真实ID列表
        '''
        allReal=[]
        for camerakey in allRealIdMap:
            allReal.extend(allRealIdMap[camerakey])
        return list(set(allReal))


